Skip to content

fix: allow non-prerendered API endpoint calls during reroute when prerendering #13616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 21, 2025

Conversation

dummdidumm
Copy link
Member

@dummdidumm dummdidumm commented Mar 20, 2025

There's a bug within reroute when prerendering:

  1. after building SvelteKit will prerender routes that are prerenderable, and crawls as part of that
  2. you start on / and on it is a link <a href="/foo">..
  3. you have a reroute that responds do that, and it calls an endpoint to get the rerouted path, /api/reroute for example, using the provided fetch
  4. Inside endpoint.js there's logic that says "if you're in prerendering, then if your depth is more than 0 error, else return undefined"
  5. boom

To fix this we need to add a new boolean to the prerendering state to not error in those situations (and also to allow query strings)


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Copy link

changeset-bot bot commented Mar 20, 2025

🦋 Changeset detected

Latest commit: 7339c10

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot
Copy link

@dummdidumm dummdidumm marked this pull request as ready for review March 20, 2025 21:42
@Rich-Harris
Copy link
Member

I ran into an error testing this locally with a prerendered /reroute/[slug] endpoint (which would be necessary for e.g. adapter-static to work properly) — because the endpoint wasn't prerendered, I hit this error:

Error: The following routes were marked as prerenderable, but were not prerendered because they were not found while crawling your app:
- /reroute/[slug]

I was able to 'fix' it by using create_universal_fetch instead of reusing event.fetch, since doing so means that state.prerendering.dependencies gets populated (and .svelte-kit/output/prerendered/dependencies/reroute/blah files get generated). But I had to gloss over some details — the fetched, csr and resolve_opts arguments are all incorrect:

--git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js
index 81b30e075..5b1ec0d7d 100644
--- a/packages/kit/src/runtime/server/respond.js
+++ b/packages/kit/src/runtime/server/respond.js
@@ -34,6 +34,7 @@ import {
        strip_resolution_suffix
 } from '../pathname.js';
 import { with_event } from '../app/server/event.js';
+import { create_universal_fetch } from './page/load_data.js';
 
 /* global __SVELTEKIT_ADAPTER_NAME__ */
 /* global __SVELTEKIT_DEV__ */
@@ -181,6 +182,13 @@ export async function respond(request, options, manifest, state) {
                });
        }
 
+       /** @type {import('types').RequiredResolveOptions} */
+       let resolve_opts = {
+               transformPageChunk: default_transform,
+               filterSerializedResponseHeaders: default_filter,
+               preload: default_preload
+       };
+
        let resolved_path;
 
        const prerendering_reroute_state = state.prerendering?.inside_reroute;
@@ -191,7 +199,10 @@ export async function respond(request, options, manifest, state) {
 
                // reroute could alter the given URL, so we pass a copy
                resolved_path =
-                       (await options.hooks.reroute({ url: new URL(url), fetch: event.fetch })) ?? url.pathname;
+                       (await options.hooks.reroute({
+                               url: new URL(url),
+                               fetch: create_universal_fetch(event, state, [], false, resolve_opts)
+                       })) ?? url.pathname;
        } catch {
                return text('Internal Server Error', {
                        status: 500
@@ -277,13 +288,6 @@ export async function respond(request, options, manifest, state) {
                }
        }
 
-       /** @type {import('types').RequiredResolveOptions} */
-       let resolve_opts = {
-               transformPageChunk: default_transform,
-               filterSerializedResponseHeaders: default_filter,
-               preload: default_preload
-       };
-
        /** @type {import('types').TrailingSlash} */
        let trailing_slash = 'never';

Not sure if you have any better ideas? I put my repro up here: https://github.com/Rich-Harris/repro-kit-13616

@dummdidumm
Copy link
Member Author

Good catch! This isn't exactly a regression from this fix but a different bug, but good to fix it regardless. I adjusted the logic in the endpoint to add the response to the prerendered dependencies if needed.

Will self-merge once green.

@dummdidumm dummdidumm merged commit c9198a3 into main Mar 21, 2025
16 checks passed
@dummdidumm dummdidumm deleted the prerender-reroute-fix branch March 21, 2025 09:51
@github-actions github-actions bot mentioned this pull request Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants